import router from "./router";
import store from "./store";
import { asyncRoutes } from "./router/asyncRoutes";
// 获取一级权限标识
function getFirstRouterPermission(permission) {
  // 获取里面每一个带有标识的冒号前面的部分
  const firstPermissionArr = permission.map((item) => {
    // 对冒号进行分割,取出来第一项
    return item.split(":")[0];
  });
  // 对获取的新数组进行去重，但得到的是一个伪数组,因此需要使用array.from()方法转化为真数组
  return Array.from(new Set(firstPermissionArr));
}
// 获取二级权限标识
function getSecondRouterPermission(permission) {
  const secondPermissionArr = permission.map((item) => {
    // 对冒号进行分割,取出来第一项
    const arr = item.split(":");
    return `${arr[0]}:${arr[1]}`;
  });
  return Array.from(new Set(secondPermissionArr));
}
// 根据一级和二级权限标识进行筛选
function getRoutes(firstPermission, secondPermission, asyncRoutes) {
  // 判断当前登陆者是不是管理员 若是，则不筛选
  if (firstPermission.includes("*")) {
    return asyncRoutes;
  }
  const firstRoutes = asyncRoutes.filter((item) =>
    firstPermission.includes(item.permission)
  );
  const routes = firstRoutes.map((item) => {
    return {
      ...item,
      children: item.children.filter((child) =>
        // 判断child的permission是否在secondPermission中
        secondPermission.includes(child.permission)
      ),
    };
  });
  return routes;
}
// 定义白名单
const whiteList = ["/login", "/404"];
router.beforeEach(async (to, from, next) => {
  // 到哪去、从哪来、放行吗？重定向吗next(路径)
  // 不绑定不生效，需要在main.ts中绑定

  // 根据是否有token判断
  if (store.state.user.token) {
    // 有token，判断是否要跳到登录页
    if (to.path === "/login") {
      // 是login
      next("/");
    } else {
      // 不是login
      next();
      //通过store实例调用,拿到用户的权限信息
      const permission = await store.dispatch("menu/getUserPermission");
      // 拿到权限标识,和router实例进行对比，筛选左侧菜单
      // 1根据权限标识，筛选出对应的一级路由
      const firstPermission = getFirstRouterPermission(permission);
      console.log(firstPermission);
      // 2根据权限标识，筛选出对应的二级路由
      const secondPermission = getSecondRouterPermission(permission);
      console.log(secondPermission);
      // 4 过滤路由,根据一级权限标识和二级权限标识和动态路由进行筛选
      const routes = getRoutes(firstPermission, secondPermission, asyncRoutes);
      console.log(routes, "xin");
      // 5.1 把筛选出来的路由渲染在左侧
      // 把每一条路由规则添加到路由实例中，动态添加路由规则
      // 做到这一步就可以访问了，但是并没有渲染在左侧，因为 this.$router.options.routes监听不到后续添加的内容，会丢失响应式
      // 为了解决这个问题 我们可以采用在vuex中存一份备份
      routes.forEach((item) => router.addRoute(item));
      // 5.2 调用方法，备份到vuex
      // 还有问题，管理员权限列表是“*”，因此无法被渲染,需要单独处理
      store.commit("menu/setMenuList", routes);
    }
  } else {
    // 没有token
    if (whiteList.includes(to.path)) {
      // 在白名单中，直接进入
      next();
    } else {
      // 不在白名单中，跳转到登录页
      next("/login");
    }
  }
  next();
});
